using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NAudio.Wave;

namespace Chat.Backend.Services.Media
{
    /// <summary>
    /// 语音消息处理服务 - 处理语音消息的编码、解码和转换
    /// </summary>
    public class VoiceService : IVoiceService
    {
        private readonly ILogger<VoiceService> _logger;
        private readonly IStorageService _storageService;
        private readonly VoiceSettings _settings;

        /// <summary>
        /// 构造函数
        /// </summary>
        public VoiceService(
            ILogger<VoiceService> logger,
            IStorageService storageService,
            IOptions<VoiceSettings> settings)
        {
            _logger = logger;
            _storageService = storageService;
            _settings = settings.Value;
        }

        /// <summary>
        /// 处理并保存语音消息
        /// </summary>
        public async Task<VoiceProcessResult> ProcessVoiceMessageAsync(byte[] audioData, string userId, AudioFormat format)
        {
            try
            {
                // 生成文件名
                var fileName = $"voice_{userId}_{Guid.NewGuid()}.{GetFileExtension(format)}";
                
                // 处理音频数据
                byte[] processedData = await ProcessAudioDataAsync(audioData, format);
                
                // 上传到存储
                var url = await _storageService.UploadFileAsync(
                    processedData, 
                    "voices", 
                    fileName, 
                    GetContentType(format));
                
                // 获取音频时长
                var duration = GetAudioDuration(processedData, format);
                
                return new VoiceProcessResult
                {
                    Success = true,
                    Url = url,
                    Duration = duration,
                    Format = format.ToString()
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"处理语音消息失败: 用户ID {userId}");
                return new VoiceProcessResult
                {
                    Success = false,
                    Error = ex.Message
                };
            }
        }

        /// <summary>
        /// 转换语音格式
        /// </summary>
        public async Task<byte[]> ConvertVoiceFormatAsync(byte[] audioData, AudioFormat sourceFormat, AudioFormat targetFormat)
        {
            try
            {
                if (sourceFormat == targetFormat)
                {
                    return audioData; // 如果格式相同，直接返回原数据
                }
                
                // 使用NAudio进行格式转换
                using (var sourceStream = new MemoryStream(audioData))
                using (var targetStream = new MemoryStream())
                {
                    // 创建适合源格式的读取器
                    WaveStream reader = null;
                    
                    switch (sourceFormat)
                    {
                        case AudioFormat.WAV:
                            reader = new WaveFileReader(sourceStream);
                            break;
                            
                        case AudioFormat.MP3:
                            reader = new Mp3FileReader(sourceStream);
                            break;
                            
                        case AudioFormat.AMR:
                            // 对于AMR格式，可能需要特殊处理或第三方库
                            throw new NotSupportedException("AMR格式转换暂不支持");
                            
                        default:
                            throw new ArgumentException($"不支持的源格式: {sourceFormat}");
                    }
                    
                    // 创建适合目标格式的写入器
                    switch (targetFormat)
                    {
                        case AudioFormat.WAV:
                            using (var writer = new WaveFileWriter(targetStream, reader.WaveFormat))
                            {
                                reader.CopyTo(writer);
                            }
                            break;
                            
                        case AudioFormat.MP3:
                            // 对于MP3编码可能需要使用LAME或其他编码器
                            using (var resampler = new MediaFoundationResampler(reader, new WaveFormat(16000, 1)))
                            {
                                MediaFoundationEncoder.EncodeToMp3(resampler, targetStream, 64000);
                            }
                            break;
                            
                        default:
                            throw new ArgumentException($"不支持的目标格式: {targetFormat}");
                    }
                    
                    return targetStream.ToArray();
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"转换语音格式失败: {sourceFormat} -> {targetFormat}");
                throw;
            }
        }

        /// <summary>
        /// 处理音频数据（如压缩、降噪等）
        /// </summary>
        private async Task<byte[]> ProcessAudioDataAsync(byte[] audioData, AudioFormat format)
        {
            // 根据需要进行音频处理，如降噪、压缩等
            // 这里仅作为示例，实际应用可能需要更复杂的处理
            
            try
            {
                // 简单处理：如果是WAV格式并且大于一定大小，转换为MP3以节省空间
                if (format == AudioFormat.WAV && audioData.Length > 1024 * 1024) // 大于1MB
                {
                    return await ConvertVoiceFormatAsync(audioData, AudioFormat.WAV, AudioFormat.MP3);
                }
                
                // 否则返回原始数据
                return audioData;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "处理音频数据失败");
                return audioData; // 处理失败时返回原始数据
            }
        }

        /// <summary>
        /// 获取音频时长（秒）
        /// </summary>
        private int GetAudioDuration(byte[] audioData, AudioFormat format)
        {
            try
            {
                using (var stream = new MemoryStream(audioData))
                {
                    switch (format)
                    {
                        case AudioFormat.WAV:
                            using (var reader = new WaveFileReader(stream))
                            {
                                return (int)reader.TotalTime.TotalSeconds;
                            }
                            
                        case AudioFormat.MP3:
                            using (var reader = new Mp3FileReader(stream))
                            {
                                return (int)reader.TotalTime.TotalSeconds;
                            }
                            
                        // 其他格式需要特定的处理方法
                        default:
                            return 0;
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取音频时长失败: 格式 {format}");
                return 0;
            }
        }

        /// <summary>
        /// 获取文件扩展名
        /// </summary>
        private string GetFileExtension(AudioFormat format)
        {
            switch (format)
            {
                case AudioFormat.WAV:
                    return "wav";
                case AudioFormat.MP3:
                    return "mp3";
                case AudioFormat.AMR:
                    return "amr";
                default:
                    return "bin";
            }
        }

        /// <summary>
        /// 获取MIME类型
        /// </summary>
        private string GetContentType(AudioFormat format)
        {
            switch (format)
            {
                case AudioFormat.WAV:
                    return "audio/wav";
                case AudioFormat.MP3:
                    return "audio/mpeg";
                case AudioFormat.AMR:
                    return "audio/amr";
                default:
                    return "application/octet-stream";
            }
        }
    }

    /// <summary>
    /// 语音消息处理服务接口
    /// </summary>
    public interface IVoiceService
    {
        Task<VoiceProcessResult> ProcessVoiceMessageAsync(byte[] audioData, string userId, AudioFormat format);
        Task<byte[]> ConvertVoiceFormatAsync(byte[] audioData, AudioFormat sourceFormat, AudioFormat targetFormat);
    }

    /// <summary>
    /// 音频格式枚举
    /// </summary>
    public enum AudioFormat
    {
        WAV,
        MP3,
        AMR
    }

    /// <summary>
    /// 语音处理结果
    /// </summary>
    public class VoiceProcessResult
    {
        /// <summary>
        /// 是否成功
        /// </summary>
        public bool Success { get; set; }
        
        /// <summary>
        /// 语音文件URL
        /// </summary>
        public string Url { get; set; }
        
        /// <summary>
        /// 时长（秒）
        /// </summary>
        public int Duration { get; set; }
        
        /// <summary>
        /// 格式
        /// </summary>
        public string Format { get; set; }
        
        /// <summary>
        /// 错误信息
        /// </summary>
        public string Error { get; set; }
    }
}